﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.IO;
using SSPComm;
using SSPComm.SSPReplies;
using SSPComm.SSPCommands;

namespace ExampleSmartHopper
{
    class Program
    {
        static private readonly Byte _commId = 0x10;

        static void Main(string[] args)
        { 
            if (args.Length == 0)
            {
                Console.Write("Argument error.\nExample: smarthoppertest.exe COM3");
                Console.ReadKey();
                return;
            }
            Console.Write("{0}.\nSee logs for more info\nStart\n", System.Reflection.Assembly.GetAssembly(typeof(SSPController)).FullName);
            SSPController sspController = new SSPController(args[0],_commId, 504884, Print, Print);
            Boolean stop = false;
            String key;
            sspController.Start();
            UInt32 value = 0;
            UInt16 count = 0;
            Byte route = 0;
			String countryCode = String.Empty;
            try
            {
                while (!stop)
                {
                    Console.Write("1. Reset\n2. Add\n3. Pay\n4. Pay quick\n5. Coins all\n6. Coin\n7. Set routing\n8. Get routing\n9. Setup\n0. Pay amount quick\na. Get serial\nb. Get state\nc. Empty all\nd. Smart empty\ne. Smart empty quick\n");
                    key = Console.ReadLine();
                    try
                    {
                        #region 1
                        if (key.StartsWith("1"))
                        {
                            sspController.Reset();
                        }
                        #endregion
                        #region 2
                        else if (key.StartsWith("2"))
                        {
                            GetValueCountAndCountryCode(out value, out count, out countryCode);
                            SSPReply rep = sspController.AddCoinAmount(value, count, countryCode);
                        }
                        #endregion
                        #region 3
                        else if (key.StartsWith("3"))
                        {
                            GetValueCountAndCountryCode(out value, out count, out countryCode);
                            SSPReply rep = sspController.PayoutDenom(value, count, countryCode);
                                //PayoutDenom(value, count);
                            SSPCoinsReply coins = rep as SSPCoinsReply;
                            if (coins != null)
                            {
                                if (coins.GetDispenced() != null)
                                {
                                    for (int i = 0; i < coins.GetDispenced().Coins.Length; i++ )
                                    {
                                        Console.Write("Dispensed: {0}\n", coins.GetDispenced().Coins[i].Value);
                                    }
                                }
                                
                                if (coins.GetTimeOut() != null)
                                {
                                    for (int i = 0; i < coins.GetTimeOut().Coins.Length; i++)
                                    {
                                        Console.Write("TimeOut: {0}\n", coins.GetTimeOut().Coins[i].Value);
                                    }
                                }

                                if (coins.GetCashBoxPaid() != null)
                                {
                                    for (int i = 0; i < coins.GetCashBoxPaid().Coins.Length; i++)
                                    {
                                        Console.Write("CashBoxPaid: {0}\n", coins.GetCashBoxPaid().Coins[i].Value);
                                    }
                                }
                            }
                        }
                        #endregion
                        #region 4
                        else if (key.StartsWith("4"))
                        {
                            sspController.PayoutDenomQuick(value, count, countryCode);
                            //Console.Write(rep.ToString());
                        }
                        #endregion
                        #region 5
                        else if (key.StartsWith("5"))
                        {
                            Dictionary<SSPCoin, UInt16> coins = sspController.GetCoinAmount();
                            Console.Write("Coin:\tAmount\n");
                            var en = coins.GetEnumerator();
                            while (en.MoveNext())
                            {
                                Console.Write("{0}\t{1}\n", en.Current.Key.Value, en.Current.Value);
                            }
                            //Console.Write(rep.ToString());
                        }
                        #endregion
                        #region 6
                        else if (key.StartsWith("6"))
                        {
                            GetValueAndCountryCode(out value, out countryCode);
                            UInt32 res = sspController.GetCoinAmount(value, countryCode);

                            Console.Write("Coin:\tValue\n");
                            Console.Write("{0}:\t{1}\n", value, res);
                        }
                        #endregion
                        #region 7
                        else if (key.StartsWith("7"))
                        {
                            //sspController.SetRouting(
                            GetValueRouteAndCountryCode(out value, out route, out countryCode);
                            SSPReply rep = sspController.SetRouting(value, route == 0 ? SSPRoute.Recycle : SSPRoute.Cashbox, countryCode);
                        }
                        #endregion
                        #region 8
                        else if (key.StartsWith("8"))
                        {
                            var res = sspController.GetRouting();
                            var en = res.GetEnumerator();
                            Console.Write("Coin:\tRouting\n");
                            while (en.MoveNext())
                            {
                                Console.Write("{0}:\t{1}\n", en.Current.Key.Value, en.Current.Value);
                            }
                        }
                        #endregion
                        #region 9
                        else if (key.StartsWith("9"))
                        {
                            SSPReply rep = sspController.GetSetup();
                            Console.Write(rep.ToString());
                        }
                        #endregion
                        #region 0
                        else if (key.StartsWith("0"))
                        {
                            //SSPReply rep = sspController.GetSetup();
                            //Console.Write(rep.ToString());
                            GetValueAndCountryCode(out value, out countryCode);
                            sspController.PayoutAmountQuick(value, countryCode);
                        }
                        #endregion
                        #region a
                        else if (key.StartsWith("a"))
                        {
                            Console.Write("{0}\n", sspController.GetSerial());
                            sspController.ValidateSerial();
                            //SSPReply rep = sspController.GetSetup();
                            //Console.Write(rep.ToString());
                            //GetValue(out value);
                            //sspController.PayoutAmountQuick(value);
                        }
                        #endregion
                        #region b
                        else if (key.StartsWith("b"))
                        {
                            SSPReply outReply;
                            String outMsg;
                            Console.Write("{0}:{1}\n", sspController.IsStateOK(out outReply, out outMsg), outMsg);
                        }
                        #endregion
                        #region c
                        else if (key.StartsWith("c"))
                        {
                            Console.Write("{0}\n", sspController.EmptyAll());
                        }
                        #endregion
                        #region d
                        else if (key.StartsWith("d"))
                        {
                            SSPReply rep = sspController.SmartEmpty();

                            SSPCoinsReply coins = rep as SSPCoinsReply;
                            if (coins != null)
                            {
                                if (coins.GetEmptied() != null)
                                {
                                    for (int i = 0; i < coins.GetEmptied().Coins.Length; i++)
                                    {
                                        Console.Write("Emptied: {0}\n", coins.GetEmptied().Coins[i].Value);
                                    }
                                }
                            }
                        }
                        #endregion
                        #region e
                        else if (key.StartsWith("e"))
                        {
                            Console.Write("{0}\n", sspController.SmartEmptyQuick());
                        }
                        #endregion
                        else
                        {
                            stop = true;
                        }
                    }
                    catch (Exception exc)
                    {
                        Console.WriteLine("Err: {0}", exc.Message);
                    }
                }
            }
            catch (Exception exc)
            {
                Console.WriteLine("Unexpected exception: {0}", exc);
            }
            finally
            {
                Console.Write("Stop\n");
                sspController.Stop();
            }
            Console.Write("Press any key...");
            Console.ReadKey();
        }

        static void Print(SSPReply inEvent)
        {
            if (inEvent is SSPCoinsReply)
            {
                Console.Write(inEvent.ToString());
            }
            else if (inEvent is SSPCalibrationReply)
            {
                Console.Write(inEvent.ToString());
            }
            else if (inEvent is SSPPollReply)
            {
                Console.Write("< {0}[{1}]\n", inEvent.Type.ToString(), (inEvent as SSPPollReply).Event.ToString());
            }
            else
            {
                Console.Write("< {0}[{1}]\n", inEvent.Type.ToString(), inEvent.ToString());
            }
        }

        static void Print(Exception inException)
        {
            Console.Write("Exception: {0}\n", inException);
        }

        static void GetValueCountAndCountryCode(out UInt32 outValue, out UInt16 outCount, out String outCountryCode)
        {
            outValue = 0;
            outCount = 0;
			outCountryCode = String.Empty;
            Console.Write("Input value (10, 50, 100, 200, 500, 1000), count and country code (EUR)\n");

            outValue = UInt32.Parse(Console.ReadLine());
            outCount = UInt16.Parse(Console.ReadLine());
			outCountryCode = Console.ReadLine();
        }

        static void GetValueRouteAndCountryCode(out UInt32 outValue, out Byte outRoute, out String outCountryCode)
        {
            outValue = 0;
            outRoute = 0;
			outCountryCode = String.Empty;
            Console.Write("Input value (10, 50, 100, 200, 500, 1000), route (0, 1) and country code (EUR)\n");

            outValue = UInt32.Parse(Console.ReadLine());
            outRoute = Byte.Parse(Console.ReadLine());
			outCountryCode = Console.ReadLine();
        }

        static void GetValue(out UInt32 outValue)
        {
            outValue = 0;
            Console.Write("Input value\n");

            outValue = UInt32.Parse(Console.ReadLine());
        }

		static void GetValueAndCountryCode(out UInt32 outValue, out String outCountryCode)
		{
			outCountryCode = String.Empty;
			outValue = 0;
			Console.Write("Input value and country code (EUR)\n");

			outValue = UInt32.Parse(Console.ReadLine());
			outCountryCode = Console.ReadLine();
		}
    }
}
